/*
	MIDAS Context Based Routing
	cbr_rreqtable.cc
	Copyright (c) 2007 Radoslaw Olgierd Schoeneich
	Copyright (c) 2007 Bartlomiej Zolnierkiewicz
	MEAG IT PW
*/

#include <list>

#include <semaphore.h>

#include "cbr_rreqtable.h"

sem_t rreqtable_sem;

cbr_RReqTable::cbr_RReqTable()
{
	sem_init(&rreqtable_sem, 0, 1);
}

cbr_RReqTable::~cbr_RReqTable()
{
	sem_destroy(&rreqtable_sem);
}

/**
 * Add RREQ request to the RREQ requests table.
 *
 * @param trID transaction ID
 * @param src CBR id of the source node
 * @param prev_hop CBR id of the previous node (hop)
 */

void cbr_RReqTable::insert(u_int32_t trID, cbr_ID src, cbr_ID prev_hop)
{
	reqs_list::iterator i;

	sem_wait(&rreqtable_sem);
	for (i = reqs.begin(); i != reqs.end(); i++) {
		if (i->trID == trID && i->src == src) {
			sem_post(&rreqtable_sem);
			return;
		}
	}

	reqs.push_back(entry(trID, src, prev_hop));
	sem_post(&rreqtable_sem);
}

/**
 * Remove RREQ request from the RREQ requests table.
 *
 * @param trID transaction ID
 * @param src CBR id of the source node
 */

void cbr_RReqTable::remove(u_int32_t trID, cbr_ID src)
{
	reqs_list::iterator i;

	sem_wait(&rreqtable_sem);
	for (i = reqs.begin(); i != reqs.end(); i++) {
		if (i->trID == trID && i->src == src) {
			reqs.erase(i);
			sem_post(&rreqtable_sem);
			return;
		}
	}
	sem_post(&rreqtable_sem);
}

/**
 * Lookup CBR id of the previous node given RREQ request data.
 *
 * @param trID transaction ID
 * @param src CBR id of the source node
 * @param prev_hop pointer to store CBR id of the previous node
 *
 * @return "true" if the given RREQ request exists in RREQ requests table,
 * "false" otherwise.
 */

bool cbr_RReqTable::getPrevHop(u_int32_t trID, cbr_ID src, cbr_ID *prev_hop)
{
	reqs_list::iterator i;

	sem_wait(&rreqtable_sem);
	for (i = reqs.begin(); i != reqs.end(); i++) {
		if (i->trID == trID && i->src == src) {
			if (prev_hop)
				*prev_hop = i->prev_hop;
			sem_post(&rreqtable_sem);
			return true;
		}
	}
	sem_post(&rreqtable_sem);

	return false;
}
